home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 May: Tool Chest / Dev.CD May 98 TC.toast / Tool Chest / Testing & Debugging / General tools / Report Error 2.0 / ReportError.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-17  |  5.5 KB  |  229 lines  |  [TEXT/KAHL]

  1. /*================================================================================
  2.     ReportError.c
  3.     
  4.     ©1991 Greg Anderson
  5.     greggor@apple.com
  6.     
  7.     FREE DISTRIBUTION
  8.     
  9.     The possessor of this source code may use any portion of
  10.     it for any purpose, and I place no restriction on its
  11.     redistribution.
  12.     
  13.     These routines are very convenient for debugging; they will convert
  14.     OSErrors from short negative numbers to human-readable strings in
  15.     Pascal format
  16.     
  17.     This code depends on:
  18.     
  19.         StringUtilities.c
  20.         DialogUtilities.c
  21.         
  22.         'DLOG' resource ID 30303    A simple dialog box for displaying errors;
  23.         'DITL' resource ID 30303    Has one 'Okay' button and one static text
  24.                                     item that reads:
  25.                                     
  26.                                     ^0 ^1
  27.                                     
  28.                                     ^2 because ^3
  29.                                     
  30.         'TEXT' resource ID 30303    All error messages, each line cr-terminated
  31.         
  32. ================================================================================*/
  33. #include "ReportError.h"
  34.  
  35. /*
  36. // Header files for utility routines:
  37. */
  38. #ifndef __DIALOGUTILITIES__
  39.     #include "DialogUtilities.h"
  40. #endif
  41. #ifndef __STRINGUTILITIES__
  42.     #include "StringUtilities.h"
  43. #endif
  44. #ifndef _FAILUREHANDLER__
  45.     #include "FailureHandler.h"
  46. #endif
  47. #ifndef __SHOWSTACKCHAIN__
  48.     #include "ShowStackChain.h"
  49. #endif
  50.  
  51. /*
  52. // Macintosh includes
  53. */
  54. #ifndef __TYPES__
  55.     #include <Types.h>
  56. #endif
  57. #ifndef __ERRORS__
  58.     #include <Errors.h>
  59. #endif
  60. #ifndef __MEMORY__
  61.     #include <Memory.h>
  62. #endif
  63. #ifndef __RESOURCES__
  64.     #include <Resources.h>
  65. #endif
  66. #ifndef __PACKAGES__
  67.     #include "Packages.h"
  68. #endif
  69.  
  70. /*
  71. // MPW requires this, but Think C 4.0.5 won't compile if
  72. // it's in (but works all the same without it).  The
  73. // error is 'Debug Table Overflow', & you can get it
  74. // just by including <Script.h> (which <Packages.h>
  75. // includes).  It looks like a size problem, because
  76. // other files can include <Script.h> with no problem.
  77. //
  78. // MPW needs <Packages.h> for 'NumToString'.
  79. */
  80. #ifndef THINK_C
  81.     #ifndef __PACKAGES__
  82.         #include <Packages.h>
  83.     #endif
  84. #endif
  85.  
  86. Handle        gResultCodeText = nil;
  87.  
  88. /*----------------------------------------------------------------------
  89.     Search for an error result code in the result code text
  90.     
  91.     Return 'false' if the name and description strings cannot be filled in
  92. ----------------------------------------------------------------------*/
  93. Boolean FindResultCodeDescription( OSErr theErr, Str255 errorNameStr, Str255 errorDescStr )
  94. {
  95.     Size        textSize;
  96.     char*        p;
  97.     Boolean        foundEntry;
  98.     OSErr        testError;
  99.     
  100.     /*
  101.     // Note that if the error is a 'memFullErr', it isn't going to do
  102.     // much good to try to load in the result code test.  Handle this
  103.     // case separately.
  104.     //
  105.     // While there are other situations that could also cause this
  106.     // routine to fail, none are as common as memFullErr.
  107.     */
  108.     if( theErr == memFullErr )
  109.     {
  110.         CtoPcpy( errorNameStr, "memFullErr" );
  111.         CtoPcpy( errorDescStr, "there is insufficient memory left in the heap zone" );
  112.         
  113.         return true;
  114.     }
  115.     /*
  116.     // If we have never loaded the result code text, do so now
  117.     */
  118.     if( gResultCodeText == nil )
  119.         gResultCodeText = GetResource( 'TEXT', kReportErrorID );
  120.     if( gResultCodeText == nil )
  121.         return false;
  122.     /*
  123.     // If the result code text has been purged, try to re-load it.
  124.     */
  125.     if( *gResultCodeText == nil )
  126.         LoadResource( gResultCodeText );
  127.     if( *gResultCodeText == nil )
  128.         return false;
  129.     /*
  130.     // Lock the result text & dereference it
  131.     */
  132.     MoveHHi( gResultCodeText );
  133.     HLock( gResultCodeText );
  134.     p = *gResultCodeText;
  135.     textSize = GetHandleSize( gResultCodeText );
  136.     foundEntry = false;
  137.     do
  138.     {
  139.         SkipToSpec( p, '-' );
  140.         if( !(*p) )
  141.             break;
  142.         ++p;
  143.         
  144.         testError = -ScanNumberInString( &p );
  145.         if( testError == theErr )
  146.         {
  147.             SkipPastWhitespace( p );
  148.             ScanWordInString( &p, errorNameStr );
  149.             SkipPastWhitespace( p );
  150.             ScanLineInString( &p, errorDescStr );
  151.             foundEntry = true;
  152.             break;
  153.         }
  154.     }
  155.     while( testError != -32767 );
  156.     /*
  157.     // Unlock the result text and return
  158.     */
  159.     HUnlock( gResultCodeText );
  160.     return foundEntry;
  161. }
  162.  
  163. /*----------------------------------------------------------------------
  164.     Put up a dialog box reporting an error to the user
  165. ----------------------------------------------------------------------*/
  166. void ReportError( Str255 errorMsg, OSErr theErr )
  167. {
  168.     DialogPtr        dlog;
  169.     short            itemHit;
  170.     Str255            errorNumberStr;
  171.     Str255            errorNameStr;
  172.     Str255            errorDescStr;
  173.     long            longErr = theErr;
  174.     
  175.     /*
  176.     // Do nothing if theErr == noErr
  177.     */
  178.     if( theErr != noErr )
  179.     {
  180.         /*
  181.         // Clear out the pascal strings, just to be safe
  182.         */
  183.         errorNameStr[0] = 0;
  184.         errorDescStr[0] = 0;
  185.         errorNumberStr[0] = 0;
  186.         /*
  187.         // Set up the error number string
  188.         */
  189.         NumToString( longErr, errorNumberStr );
  190.         FindResultCodeDescription( theErr, errorNameStr, errorDescStr );
  191.         if( errorDescStr[0] == 0 )
  192.             CtoPcpy( errorDescStr, "an error ocurred" );
  193.         /*
  194.         // Set up Dialog box
  195.         */
  196.         dlog = GetNewDialog(kReportErrorID, (Ptr)0L, (WindowPtr)-1L);
  197.         if( dlog != nil )
  198.         {
  199.             SetPort( dlog );
  200.             ParamText( errorMsg, errorNumberStr, errorNameStr, errorDescStr );
  201.             SelectWindow(dlog);
  202.             InstallDefaultOutline( dlog, kReportErrorOK );
  203.             if(!ExceptionNotifyProcInstalled())
  204.                 HideDItem(dlog,kReportErrorSC6);
  205.             CenterAndShowDialog(dlog);
  206.             InitCursor();
  207.             /*
  208.             // Wait for user to click "Okay" or "sc6"
  209.             */
  210.             do
  211.             {
  212.                 ModalDialog((ModalFilterProcPtr) CutPasteFilter, &itemHit);
  213.             } while( (itemHit != kReportErrorOK) && (itemHit != kReportErrorSC6) );
  214.             DisposDialog(dlog);
  215.             /*
  216.             // If user hit 'sc6', then show the stack chain
  217.             */
  218.             if(itemHit == kReportErrorSC6)
  219.             {
  220.                 ShowFailureStackChain("\pStack chain at time of failure (tracing A6 links):");
  221.             }
  222.         }
  223.         else
  224.         {
  225.             DebugStr("\pReportError could not bring up dialog box");
  226.         }
  227.     }
  228. }
  229.